package models.weixin.auth;

import cache.CacheHelper;
import helper.GlobalConfig;
import models.merchant.Merchant;
import models.weixin.WebUser;
import org.apache.commons.lang.StringUtils;
import play.Logger;
import play.Play;
import play.mvc.After;
import play.mvc.Before;
import play.mvc.Controller;
import utils.ObjectUtil;


/**
 * 微信公众号认证，基于OAuth.
 */
public class WxMpAuth2 extends Controller {


    private final static ThreadLocal<WebUser> _currentUser = new ThreadLocal<>();
    private final static ThreadLocal<Merchant> _currentMerchant = new ThreadLocal<>();

    /**
     * 检查是否已经OAuth认证过，如果没有，则调用认证.
     * @throws Throwable
     */
    @Before(unless = {"login", "logout", "fail", "validate", "validation", "authenticate", "captcha"})
    public static void filter() throws Throwable {
        String linkId = params.get("linkId");
        if(linkId != null) {
            session.put("linkId" , linkId);
        } else {
            linkId = session.get("linkId");
        }
        if(ObjectUtil.checkBlock(linkId)) {
            // linkId 不存在。 要打回到 一个错误页面
            redirect("/weixin/errors/404.html");
        }
        Merchant merchant = Merchant.findByLinkId(linkId);
        if(merchant == null){
            redirect("/weixin/errors/404.html");
        }
        renderArgs.put("merchant" , merchant);
        _currentMerchant.set(merchant);

        WebUser webUser = WebUser.findById(1l);
        _currentUser.set(webUser);
        renderArgs.put("webuser" , webUser);
        session.put(GlobalConfig.WEIXIN_MP_WEIXIN_SESSION_USER_KEY + merchant.weixinData.id , webUser.id);

    }

    @After
    public static void cleanCurrentUser() {
        _currentUser.remove();
    }

    /**
     * 在Controller中使用WexinCpAuth可以得到当前用户.
     */
    public static WebUser currentUser() {
        return _currentUser.get();
    }

    /**
     * 在Controller中使用商户
     */
    public static Merchant currentMerchant() {
        return _currentMerchant.get();
    }

    /**
     * 在Controller中使用WexinCpAuth可以得到当前用户.
     * 该用户为数据库用户. 从数据库仲更新数据
     */
    public static WebUser currentUpdateUser() {
        WebUser cacheUser = _currentUser.get();
        if(Play.mode.isDev()) {
            cacheUser = WebUser.findById(1l);
        }
        if(cacheUser == null) {
            return null;
        }
        return WebUser.findById(cacheUser.id);
    }


    public static void logout(Merchant merchant) {
        String sessionUserId = session.get(GlobalConfig.WEIXIN_MP_WEIXIN_SESSION_USER_KEY + merchant.weixinData.id);
        if(StringUtils.isNotBlank(sessionUserId)) {
            CacheHelper.delete(WebUser.WXMP_CACHEKEY + sessionUserId);
        }
        session.clear();
    }

    /**
     * 检查是否要跳过认证检查.
     *
     * @return 返回true表明跳过检查.
     */
    private static boolean skipAuthCheck() {
        if (getActionAnnotation(SkipAuth.class) != null ||
                getControllerInheritedAnnotation(SkipAuth.class) != null) {
            Logger.info("skipAuthCheck=true");
            return true;
        }
        Logger.info("skipAuthCheck=false");
        return false;
    }

    /**
     * 检查是否要使用JSAPI.
     *
     * 在类名或方法上使用@UseJsAPI标注，会在renderArgs中加入一个jsSignature的对象.
     *
     * @return UseJsAPI，其value指定需要的权限.
     */
    private static UseJsApi getUseJsAPI() {
        if (getActionAnnotation(UseJsApi.class) != null) {
            Logger.info("UseJsAPI on Action");
            return getActionAnnotation(UseJsApi.class);
        }
        if (getControllerInheritedAnnotation(UseJsApi.class) != null) {
            Logger.info("UseJsAPI on Controller");
            return getControllerInheritedAnnotation(UseJsApi.class);
        }
        Logger.info("UseJsAPI=false");
        return null;
    }

}
